package com.jay.compass;

import com.jay.compass.view.CompassView;

import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.AccelerateInterpolator;
import android.widget.TextView;

public class CompassActivity extends Activity {

	private final float MAX_ROTATE_DEGREE = 1.00f;
	private SensorManager mSensorManager;
	private Sensor mOrientationSensor;
	private float mDirection;
	private float mTargetDirection;
	private AccelerateInterpolator mInterpolator;
	protected final Handler mHandler = new Handler();
	private boolean mStopDrawing;
	private boolean mChinease;

	View mCompassView;
	CompassView mPointer;
	TextView directionTextView;

	protected Runnable mCompassViewUpdater = new Runnable() {
		@Override
		public void run() {
			if (mPointer != null && !mStopDrawing) {
				if (mDirection != mTargetDirection) {
					float to = mTargetDirection;
					if (to - mDirection > 180) {
						to -= 360;
					} else if (to - mDirection < -180) {
						to += 360;
					}

					// limit the max speed to MAX_ROTATE_DEGREE
					float distance = to - mDirection;
					if (Math.abs(distance) > MAX_ROTATE_DEGREE) {
						distance = distance > 0 ? MAX_ROTATE_DEGREE
								: (-1.0f * MAX_ROTATE_DEGREE);
					}

					mDirection = normalizeDegree(mDirection
							+ ((to - mDirection) * mInterpolator
									.getInterpolation(Math.abs(distance) > MAX_ROTATE_DEGREE ? 0.4f
											: 0.3f)));
					mPointer.updateDirection(mDirection);
				}
				updateDirection();
				mHandler.postDelayed(mCompassViewUpdater, 20);
			}
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		getWindow().setFlags(
				WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
				WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
		setContentView(R.layout.activity_compass);

		mDirection = 0.0f;
		mTargetDirection = 0.0f;
		mInterpolator = new AccelerateInterpolator();
		mStopDrawing = true;
		// mCompassView = findViewById(R.id.view_compass);
		directionTextView = (TextView) findViewById(R.id.direction_textView);
		mPointer = (CompassView) findViewById(R.id.compass_pointer);
		initServices();
	}

	@SuppressWarnings("deprecation")
	private void initServices() {
		mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
		mOrientationSensor = mSensorManager
				.getDefaultSensor(Sensor.TYPE_ORIENTATION);
	}

	@Override
	protected void onResume() {
		super.onResume();
		if (mOrientationSensor != null) {
			mSensorManager.registerListener(mOrientationSensorEventListener,
					mOrientationSensor, SensorManager.SENSOR_DELAY_GAME);
		}
		mStopDrawing = false;
		mHandler.postDelayed(mCompassViewUpdater, 20);
	}

	@Override
	protected void onPause() {
		super.onPause();
		mStopDrawing = true;
		if (mOrientationSensor != null) {
			mSensorManager.unregisterListener(mOrientationSensorEventListener);
		}
	}

	private void updateDirection() {
		float direction = normalizeDegree(mTargetDirection * -1.0f);
		StringBuilder sb = new StringBuilder();

		if (direction > 22.5f && direction < 157.5f) {
			// east
			sb.append("东");
		} else if (direction > 202.5f && direction < 337.5f) {
			// west
			sb.append("西");
		}

		if (direction > 112.5f && direction < 247.5f) {
			// south
			sb.append("南");
		} else if (direction < 67.5 || direction > 292.5f) {
			// north
			sb.append("北");
		}
		sb.append(" ");
		int direction2 = (int) direction;
		boolean show = false;
		if (direction2 >= 100) {
			sb.append(direction2 / 100);
			direction2 %= 100;
			show = true;
		}
		if (direction2 >= 10 || show) {
			sb.append(direction2 / 10);
			direction2 %= 10;
		}
		sb.append(direction2);
		directionTextView.setText(sb.toString() + "°");
	}

	private SensorEventListener mOrientationSensorEventListener = new SensorEventListener() {
		@Override
		public void onSensorChanged(SensorEvent event) {
			float direction = event.values[0] * -1.0f;
			mTargetDirection = normalizeDegree(direction);
		}

		@Override
		public void onAccuracyChanged(Sensor sensor, int accuracy) {

		}
	};

	private float normalizeDegree(float degree) {
		return (degree + 720) % 360;
	}
}
